
module Pan
  class ValidationError < Exception
  end

  class FormDialog < Component

    def rows
      subclass_responsibility
    end

    def label_for_selector(sym)
      subclass_responsibility
    end

    def rendering_selector_for(sym)
      "render_#{sym}_on".to_sym
    end

    def setter_selector_for(sym)
      "#{sym}=".to_sym
    end

    def getter_selector_for(sym)
      sym
    end
      
    def render_on(html)
      html.span(:class=>'dialog-validation') {
        html.lit(@err) if @err
      }
      html.table(:class=>'dialog') {
        html.form {
          rows.each do |sym|
            render_row_on(sym, html)
          end
          html.tr {
            html.td('colspan'=>2) {
              render_sumbit_on(html)
            }
          }
          }
        }
    end
    
    def validate_model
      model.validate_and_save
    end

    def render_sumbit_on(html)
      html.submit { |*args|
        begin
           validate_model
        rescue Pan::ValidationError => e  # FIX, not the proper prefix
          @err = e.message
        else
          @err = nil
          self.ok
        end
      }
    end

    def render_row_on(sym, html)
      html.tr {
        html.td(:class=>'label') {
          render_label_on(sym, html)
        }
        html.td {
          render_input_field_on(sym, html)
        }
      }
    end
    
    def render_label_on(sym, html)
      html.lit(label_for_selector(sym))
    end

    def render_input_field_on(sym, html)
      if self.respond_to?(rendering_selector_for(sym)) 
        render_custom_input_field(sym, html)
      else 
        render_default_input_field_on(sym, html)
      end
    end

    def render_custom_input_field(sym, html)
      self.send(rendering_selector_for(sym), html) 
    end

    def render_default_input_field_on(sym, html)
      value = model.send(getter_selector_for(sym))
      html.input('type'=>'text','value'=>value) {|val|
        model.send(setter_selector_for(sym),val)
      }
    end

  end

  class SimpleDialog < Component
    def initialize
      @messages = []
    end
    def add_message(str)
      @messages << str
      self
    end
    def render_on(html)
      render_messages_on(html)
      render_buttons_on(html)
    end

    def render_messages_on(html)
      @messages.each { |msg|
        html.p { html.lit(msg) }
      }
    end

    def render_buttons_on(html)
      html.form {
        html.submit('value'=>'Ok') { answer("ok") }      }
    end
  end

  class YesNoDialog < SimpleDialog
    def render_buttons_on(html)
      html.form {
        html.submit('value'=>'Yes') { answer(true) }
        html.submit('value'=>'No') { answer(false) }
      }
    end
  end
end
